
package biblio.util;


/**
 * A timer utility to measure time in milliseconds or nanoseconds. It measures
 * time from invoking start() method to invoking stop() method in part of second
 * set in the constructor as parameter.
 *
 * @see tryton.util.TimerMode
 *
 * @author mephisto
 * 2011-08-13
 */
public class Timer
{
    /**
     * Creates a new Timer in the specified mode.
     * 
     * @param mode a timer mode to set
     */
    public Timer(TimerMode mode)
    {
        timerMode = mode;
    }

    /**
     * Starts the timer.
     */
    public void start()
    {
        switch(timerMode)
        {
            case MILLIS:
                start = end = System.currentTimeMillis();
                break;
            case NANOS:
                start = end = System.nanoTime();
                break;
        }
        isStarted = true;
    }

    /**
     * Stops the timer.
     *
     * @throws IllegalStateException if stop() is used before start() is running.
     */
    public void stop()
    {
        AuxClass.checkArgument(isStarted, new IllegalArgumentException("Timer was not started!"));
        switch(timerMode)
        {
            case MILLIS:
                end = System.currentTimeMillis();
                break;
            case NANOS:
                end = System.nanoTime();
                break;
        }
        isStopped = true;
    }

    /**
     * Returns time between invoking start() end end() methods in the unit
     * specified by setting TimerMode.
     *
     * @return time between invoking start() end end() methods in the unit
     * specified by setting TimerMode
     *
     * @throws IllegalStateException if stop() is used before start() is running.
     *         or Timer was not stopped after was started or both methods was not
     *         used.
     */
    public long getTime()
    {
        if (!isStarted)
            throw new IllegalArgumentException("Timer was not started!");
        if (!isStopped)
            throw new IllegalArgumentException("Timer was not stopped!");
        return end-start;
    }


    private TimerMode timerMode;
    private long start;
    private long end;
    public boolean isStarted = false;
    public boolean isStopped = false;
}
